﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using EnvDTE;
using EnvDTE80;
using DoxygenBrowser.Common.Model;
using DoxygenBrowserAddin.Utils;


namespace DoxygenBrowserAddin.Controller
{
    public class CmdNavigateFromHere : AddInCommand
    {
        public CmdNavigateFromHere(string strShortName, DoxAddinController controller)
            : base(strShortName, controller)
        {
            _strButtonText = "Navigate From Here";
            _strToolTipText = "Executes the command for DoxygenAddin";
            _iIconID = 59;
            _strHotKey = "Text Editor::CTRL+F1,CTRL+F2";
        }

        public override bool Execute(vsCommandExecOption executeOption, ref object varIn, ref object varOut)
        {
            CodeLocation codeLocation = codeElementFromPoint(_controller.Application);

            if (_controller.IsDictionaryLoaded)
            {
                string innerScope = codeLocation.InnerScope;
                FileLocation fileLocation = _controller.TokenDictionary.Find(innerScope);
                string message;
                if (fileLocation != null)
                {
                    string strPath = _controller.GetDoxHtmlDirectory();

                    if (!string.IsNullOrEmpty(strPath))
                    {
                        strPath += "\\";
                    }

                    strPath += fileLocation.FullPath;
                    message = string.Format("Navigate to {0}", innerScope);
                    _controller.BrowserView.Navigate(strPath);
                    _controller.ToolWindow.Activate();

                }
                else
                {
                    message = string.Format("{0} : Not match found.", innerScope);
                }
                _controller.BrowserView.SetStatusMessage(message);
            }
            return base.Execute(executeOption, ref varIn, ref varOut);
        }

        public override void QueryStatus(vsCommandStatusTextWanted neededText, ref EnvDTE.vsCommandStatus status, ref object commandText)
        {
            base.QueryStatus(neededText, ref status, ref commandText);


            Solution solution = _controller.Application.Solution;
            status = (vsCommandStatus)(status & ~vsCommandStatus.vsCommandStatusEnabled);
            if ((solution != null) && (solution.IsOpen) && (_controller.IsDictionaryLoaded))
            {
                status = (vsCommandStatus)(status | vsCommandStatus.vsCommandStatusEnabled);
            }

        }

        private CodeLocation codeElementFromPoint(DTE2 dte)
        {
            CodeLocation codeLocation = new CodeLocation();
            if (dte.ActiveDocument != null)
            {
                TextSelection sel =
                    (TextSelection)dte.ActiveDocument.Selection;
                TextPoint pnt = (TextPoint)sel.ActivePoint;
                // Discover every code element containing the insertion point.
                FileCodeModel fcm =
                    dte.ActiveDocument.ProjectItem.FileCodeModel;

                foreach (vsCMElement codeModElem in Enum.GetValues(typeof(vsCMElement)))
                {
                    CodeElement codeElement;
                    try
                    {
                        codeElement = fcm.CodeElementFromPoint(pnt, codeModElem);
                        codeLocation.CodeScope.Add(codeModElem, codeElement.FullName);
                    }
                    catch (Exception)
                    {
                        // generate an exception if it doesn't find anything
                    }
                }
            }

            return codeLocation;
        }
    }
}
